import os
import logging
import sys
import cloudfiles
import ConfigParser
from prettytable import PrettyTable

class CloudFilesCli():
    """
    This class acts as the interface to the cloufiles backend.  The cfc client will use this to do
    work.
    """
    conn = None
    username = None
    apikey = None
    container = None
    cname_to_get = None
    download_path = None
    file_to_upload = None
    
    GREEN = '\033[92m'
    CLEAR = '\033[0m'

    config = ConfigParser.RawConfigParser()
    try:
        config.read('/etc/cfcli.conf') 
    except IOError:
        fp = open('/etc/cfcli.conf', 'w')
        print fp
        default_config = """
[auth]
username=None
apikey=None

[configuration]
default_container_name=None
logfile=/var/log/cfcli.log
        """
        fp.write(default_config)
        fp.close()
        config.read('/etc/cfcli.conf')

    logging.basicConfig(filename="%s" % config.get("configuration", "logfile"), format='[%(asctime)s]: %(message)s', level=logging.DEBUG, datefmt="%m/%d/%Y %I:%M:%S %p")
    logger = logging.getLogger()
    logger.propagate = False


    def __init__(self, *args, **kwargs):
        self.attempt_to_set_defaults()
 
    def attempt_to_set_defaults(self):
        try:
            fp = open('/etc/cfcli.conf', 'r')
            self.config.read('/etc/cfcli.conf')
        except IOError:
            fp = open('/etc/cfcli.conf', 'w')
            default_config = """
[auth]
username=None
apikey=None

[configuration]
default_container_name=None
logfile=/var/log/cfcli.log
                """
            fp.write(default_config)
    #        self.logger.info("Default configuration file created in /etc/cfcli.conf")
            fp.close()
            self.config.read('/etc/cfcli.conf')

        username = self.config.get("auth", "username")
        if username != "None":
            self.username = username
        else:
            self.get_username()
            self.config.set("auth", "username", self.username)
            self.logger.info("Set username in conf file to: %s" % self.username)

        apikey = self.config.get("auth", "apikey")
        if apikey != "None":
            self.apikey = apikey
        else:
            self.get_apikey()
            self.config.set("auth", "apikey", self.apikey)
            self.logger.info("Set apikey in conf file to: %s" % self.apikey)

        default_container_name = self.config.get("configuration", "default_container_name")
        if default_container_name != "None":
            self.cname_to_get = default_container_name
        else:
            self.get_container_name()
            self.config.set("configuration", "default_container_name", self.cname_to_get)
            self.logger.info("Default Container Name in conf set to: %s" % self.cname_to_get)

        with open('/etc/cfcli.conf', 'w') as configfile:
            self.config.write(configfile)
            self.logger.info("Default Values initialized in configuration file: /etc/cfcli.conf")

            
    def dump_variables(self):
        self.logger.info("Dumping class variables: locals(), vars(self)")
        _locals = locals()
        variables = vars(self)
        table = PrettyTable(["Name", "Value"])
        for l in _locals:
            table.add_row([l, _locals[l]])
        for v in variables:
            table.add_row([v, variables[v]])
        print table
        


    def get_username(self):
        input = raw_input("Username for Cloud Files: ")
        self.username = input
    
    def get_apikey(self):
        input = raw_input("Api key: ")
        self.apikey = input

    def get_container_name(self):
        input = raw_input("Container to load: ")
        self.cname_to_get = input
        self.get_container()

    def get_file_to_upload(self):
        input = raw_input("File to upload: ")
        self.file_to_upload = input

    def get_connection(self):
        self.conn = cloudfiles.get_connection(self.username, self.apikey)
        self.logger.info("Connection to cloudfiles achieved! %s" % self.conn)
        

    def get_container(self):
        if self.conn is None:
            self.get_connection()
        self.container = self.conn.get_container(self.cname_to_get)
        self.logger.info("Retrieved container: %s." % self.cname_to_get)
    

    def create_container(self, container_to_create=None):
        if container_to_create is None:
            input = raw_input("What would you like to name it? ")
            try:
                self.conn.create_container(input)
                print "Container: %s created!" % input
                self.logger.info("Created Container: %s" % input)
            except Exception:
                print "Container Creation Failed"
                self.logger.error("Container Creation Failed: %s" % e)
        else:
            try:
                self.conn.create_container(container_to_create)
                container = self.conn.get_container(container_to_create)
                return [0, container]
            except Exception:
                return [1, None]

    def delete_container(self, container_to_delete=None):
        if container_to_delete is None:
            c_to_del = raw_input("Which container do you want to delete? ")
            try:
                self.conn.delete_container(c_to_del)
                print "Deleted: %s!" % c_to_del
                self.logger.info("Deleted Container: %s" % c_to_del)
            except Exception as e:
                print "Deletion failed: %s" % e
                self.logger.error("Delete container failed: %s" % e)
                return
        else:
            try:
                self.conn.delete_container(container_to_delete)
                return 0
            except Exception:
                return 1

    def delete_object(self):
        if self.container is None:
            self.get_container()
        o_to_del = raw_input("Which object do you want to delete? ")
        try:
            self.container.delete_object(o_to_del)
            print "Deleted: %s" % o_to_del
        except Exception as e:
            print "Object deletion failed: %s" % e
            return


    def list_containers(self):
        containers = self.conn.list_containers()
        table = PrettyTable(["Container Name"])
        for c in containers:
            table.add_row([c])
        print table
            
        
    def list_container_objects(self):
        if self.container is None:
            self.get_container()
        
        object_details = self.container.list_objects_info()
        table = PrettyTable(['Object', 'Size', 'Modified', 'C-Type'])
        msg = "Objects in Container: %s\n" % self.cname_to_get
        print msg
        for object in object_details:
            table.add_row([object['name'], object['bytes'], object['last_modified'], object['content_type']])
        msg = "Object Count: %s" % len(object_details)
        print table
        print msg

    def upload_object(self):
        if self.file_to_upload is None:
            self.get_file_to_upload()

        if self.file_to_upload:
            input = raw_input("Is [ %s ] the proper file to upload? ")
            if 'no' in input:
                self.get_file_to_upload()
                

        if self.container is None:
            self.get_container()
       
        objname = raw_input("Object file name: ") 
        obj = self.container.create_object(objname)
        try:
            obj.load_from_filename(self.file_to_upload)
            print "Object uploaded to Cloudfiles Container: %s" % self.container
            self.logger.info("Object: %s uploaded to Container: %s" % ( objname, self.container ))
        except Exception as e:
            print "Object upload failed: %s" % e
            self.logger.error("Object upload failed: %s" % e)
            return
        


            
